<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack</title>
    <style>
        .left {
            width: 40%;
            float: left;
        }

        .center {
            float: left;
            text-align: center;
            width: 19%;
        }

        .right {
            width: 40%;
            float: right;
        }

        pre,
        div.sub,
        ul.sub {
            padding: 4px;
            border-radius: 4px;
            display: block;
            /*margin-right: 40px;*/
            background-color: #efefef;
        }
    </style>
    <script>
        setInterval(function () {
            var img = document.getElementById('coding');
            img.setAttribute('src', 'image/coding.gif');
        }, 5200);
    </script>
</head>
<body>
<h2>Web前端开发</h2>

<div>伴随着移动互联的大潮，当今越来越多的网站已经从网页模式进化到了 Webapp 模式。它们运行在现代的高级浏览器里，使用 HTML5、 CSS3、 ES6
    等更新的技术来开发丰富的功能，网页已经不仅仅是完成浏览的基本需求，并且webapp通常是一个SPA(Single Page Application)应用，每一个视图通过异步的方式加载，这导致页面初始化和使用过程中会加载越来越多的
    JavaScript 代码，这给前端开发的流程和资源组织带来了巨大的挑战。
</div>
<h2>Webpack是什么?</h2>

<div>Webpack 是当下最热门的前端资源模块化管理和打包工具。它将根据模块的依赖关系进行静态分析，然后将这些模块按照指定的规则生成对应的静态资源。
    它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔，等到实际需要的时候再异步加载。通过 loader
    的转换，任何形式的资源都可以视作模块，比如 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、 LESS 等。
</div>
<div><img height="600" src="image/what-is-webpack.png"></div>
<h2>Example</h2>

<div style="display: block;">
    <div class="left">
        <div style="height: 40px;background: #ff4400; color: white; text-align: center">Title</div>
        <div style="height: 1px; background: #efefef"></div>
        <div style="height: 24px;background: #ff4400; color: white">Menu</div>
    </div>
    <div class="center" style="text-align: center;padding-top: 22px;">
        <img height="20px" src="image/arrow_right.jpg">
    </div>
    <div class="right">
        <div style="height: 40px;background: #ff4400; color: white; text-align: center">Title</div>
        <div style="height: 1px; background: #efefef"></div>
        <div style="height: 24px;background: #71d866; color: white">Menu</div>
    </div>
</div>
<div style="display: block;">
    <div class="left">
        <pre>
.title{
    background: #ff4400
}
.menu{
    background: #ff4400
}
...
        </pre>
    </div>
    <div class="center" style="padding-top: 24px;padding-left: 4px">
        <img src="image/coding.gif" id="coding">
    </div>
    <div class="right">
        <pre>
.title{
    background: #ff4400
}
.menu{
    background: #71d866
}
...
        </pre>
    </div>
</div>
<div style="clear: both;"></div>
<h3>语义化css Sass, LESS, Stylus</h3>

<div>CSS 预处理器是一种语言用来为 CSS 增加一些编程的的特性，无需考虑浏览器的兼容性问题，例如你可以在 CSS 中使用变量、简单的程序逻辑、函数等等在编程语言中的一些基本技巧，
    可以让你的 CSS 更见简洁，适应性更强，代码更直观等诸多好处，告别石器时代。
</div>
<div>以Sass为例: Sass的变量必须是 $ 开始，然后变量名和值使用冒号隔开，跟 CSS 的属性一致</div>
<pre>
$mainColor: #0982c1;
$siteWidth: 1024px;
$borderStyle: dotted;

body {
  color: $mainColor;
  border: 1px $borderStyle $mainColor;
  max-width: $siteWidth;
}
</pre>

<div style="display: block;">
    <div class="left">
        <pre>
$titleBgColor: #ff4400
$menuBgColor: #ff4400
.title{
    background: $titleBgColor
}
.menu{
    background: $menuBgColor
}
...
        </pre>
    </div>
    <div class="center" style="padding-top: 33px; padding-left: 4px">
        <img height="107" src="image/coding2.gif">
    </div>
    <div class="right">
        <pre>
$titleBgColor: #ff4400
$menuBgColor: #71d866
.title{
    background: $titleBgColor
}
.menu{
    background: $menuBgColor
}
...
        </pre>
    </div>
</div>
<div style="clear: both;"></div>
<h3>React</h3>

<div>React 通常使用jsx语法来编写web应用程序，而不是传统的js语法；</div>
<pre>
import React from 'react';
import ReactDOM from 'react-dom';

const App = React.createClass({
    render() {
        return <div>HelloWorld</div>
    }
});

ReactDOM.render(<App/>, document.body);
</pre>
<div style="clear: both;"></div>
<h3>
    <a style="padding-bottom: 4px;">然而问题来了, 浏览器并不能直接识别语义化的css, 以及jsx语法编写的React应用程序。</a>
    <img height="26" src="image/ku.jpeg">
    <img height="26" src="image/ku.jpeg">
    <img height="26" src="image/ku.jpeg">
</h3>

<div> Webpack 正好可以帮助我们把语义化的css转换成浏览器可识别的css, 以及将jsx语法转换成普通的js程序，当然，Webpack能做的远不止这些；</div>
<h2>其它场景</h2>
<ul class="sub">
    <li>
        1. 模块化编程: 对于js来说, 将需要在多个地方使用到的js代码, 以模块的形式封装提供给调用者, webpack在打包的时候, 会自动将某个功能模块所依赖的模块打包到项目目标文件中;
        除开js之外, webpack 将一切视为模块, 包括但不限于json, css, 图片等;
    </li>
    <li>2. 按需加载: 对于大型web应用而言, 如果一次性加载所有模块, 将会造成首屏加载缓慢甚至假死, 影响用户体验;</li>
</ul>
<h2>Webpack特点</h2>
<ul>
    <li>
        <h4>代码拆分</h4>

        <div class="sub">
            Webpack 有两种组织模块依赖的方式，同步和异步。异步依赖作为分割点，形成一个新的块。在优化了依赖树后，每一个异步区块都作为一个文件被打包。
        </div>
    </li>
    <li>
        <h4>Loader</h4>

        <div class="sub">
            Webpack 本身只能处理原生的 JavaScript 模块，但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样，任何资源都可以成为 Webpack 可以处理的模块。
        </div>
    </li>
    <li>
        <h4>智能解析</h4>

        <div class="sub">
            Webpack 有一个智能解析器，几乎可以处理任何第三方库，无论它们的模块形式是 CommonJS、 AMD 还是普通的 JS 文件。甚至在加载依赖的时候，允许使用动态表达式
            require("./templates/" +
            name + ".jade")。
        </div>
    </li>
    <li>
        <h4>插件系统</h4>

        <div class="sub">
            Webpack 还有一个功能丰富的插件系统。大多数内容功能都是基于这个插件系统运行的，还可以开发和使用开源的 Webpack 插件，来满足各式各样的需求。
        </div>
    </li>
</ul>
<h2>HelloWorld</h2>
<ul>
    <li>
        <h3>安装</h3>
        <pre>npm install webpack -g</pre>
        或者
        <pre>npm install webpack --save</pre>
    </li>
    <li>
        <h3>How to use?</h3>
<pre>
// app.js
var a = require('./m.js');
// m.js
console.log('HelloWorld');
</pre>
        <pre>webpack app.js bundle.js</pre>
<pre>
Hash: 09485ee327197da8ed2b
Version: webpack 1.14.0
Time: 38ms
 Asset     Size  Chunks             Chunk Names
bundle.js  1.39 kB       0  [emitted]  main
   [0] ./app.js 0 bytes {0} [built]
</pre>
        <div>查看打包后的文件</div>
<pre>
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	var a = __webpack_require__(1);

/***/ },
/* 1 */
/***/ function(module, exports) {

	console.log('HelloWorld');

/***/ }
/******/ ]);
</pre>
    </li>
    <li>
        <h3>__webpack_require__</h3>
<pre>
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
</pre>
        <div>webpack在加载模块的时候, 首先检查该模块是否已经加载, 如果已经加载, 则直接返回缓存中的模块, 如果未加载, 则先加载, 存进缓存, 再返回;</div>
    </li>
    <li>
        <h3>模块区分</h3>
<pre>
/* 1 */
/***/ function(module, exports) {

	console.log('HelloWorld');

/***/ }
</pre>
        <div>Webpack会为每一个模块分配一个int类型 id, 需要用到该模块的时候, 通过该模块id进行加载相应的模块;</div>
    </li>
</ul>
<h2>It's not enough</h2>

<div>光使用上面的命令, 还远远发挥不出webpack的特性; 通常在项目中需要结合配置文件来使用, 配置文件默认webpack.config.js, 直接使用 webpack 命令即可进行打包;</div>
<pre>
module.exports = {
    entry: "./index.js",
    output: {
        filename: "bundle.js",
        path: "public"
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "babel-loader"
            }
        ]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin(),
    ]
}
</pre>
<div>也可以使用 <strong>webpack --config webpack.config.test.js</strong> 来指定打包所需要使用的配置文件;</div>
<ul>
    <li>
        <h3>entry</h3>
<pre>
  entry: {
    bundle1: './main1.js',
    bundle2: './main2.js'
  },
</pre>
    </li>
    <li>
        <h3>output</h3>
<pre>
  output: {
    filename: '[name].js',
    path: "public"
  }
</pre>
    </li>
    <li>
        <h3>loaders</h3>
<pre>
{
    test: /\.js$/,
    exclude: /node_modules/,
    include: /.../,
    loader: "babel-loader"
}
...
</pre>
    </li>
    <li>
        <h3>plugins</h3>

        <div class="sub">
            插件(Plugins)是用来拓展Webpack功能的，它们会在整个构建过程中生效，执行相关的任务。
            loaders是在打包构建过程中用来处理源文件的，一次处理一个，插件并不直接操作单个文件，它直接对整个构建过程起作用;
            <br/>
            比如 UglifyJsPlugin 这个插件, 会将打包之后的js文件进行压缩, 以缩小js文件体积;
        </div>
    </li>
</ul>
<h3>How to write a loader/plugin configuration?</h3>

<div>官网或者它的主页都有写如何配置</div>
<div><a href="styleloader.html">Example</a></div>
</body>
</html>